#ifndef __UTILS_H_
#define __UTILS_H_

#define MAX_ANIM 200


class CSceneBase;
class COgreEngine;

namespace Utils
{
	template<class T>
	inline T cosineInterpolate(T const &start, T const &end, Real const t)
	{
		if (t <= 0)
		{
			return start;
		}
		else
		if (t >= 1)
		{
			return end;
		}


		T output;
		for (unsigned int i = 0; i < sizeof(T) / sizeof(float); ++i)
		{
			Real mu2 = (1.0f - Math::Cos(t * Math::PI)) / 2.0f;
			output[i] = start[i] * (1 - mu2) + end[i] * mu2;
		}

		return (output);
	}

	template<class T>
	inline T linearInterpolate(T const &start, T const &end, Real const t)
	{
		if (t <= 0)
		{
			return start;
		}
		else
		if (t >= 1)
		{
			return end;
		}


		T output;
		for (unsigned int i = 0; i < sizeof(T) / sizeof(float); ++i)
		{
			output[i] = start[i] * (1 - t) + end[i] * t;
		}

		return (output);
	}

	template<class T>
	inline T cubicInterpolate(T const &before, T const &start, T const &end, T const &after, Real const t)
	{
		if (t <= 0)
		{
			return start;
		}
		else
		if (t >= 1)
		{
			return end;
		}


		T output;
		for (unsigned int i = 0; i < sizeof(T) / sizeof(float); ++i)
		{
			Real mu2 = t * t;
			Real a0 = after[i] - end[i] - before[i] + start[i];
			Real a1 = before[i] - start[i] - a0;
			Real a2 = end[i] - before[i];
			Real a3 = start[i];

			output[i] = a0 * t * mu2 + a1 * mu2 + a2 * t + a3;
		}

		return (output);
	}

	template<class T>
	inline T bestInterpolate(std::vector<T> const &vec, Real const t)
	{
		size_t const size = vec.size();
		if (size >= 4)
		{
			return cubicInterpolate(vec[size - 4], vec[size - 3], vec[size - 2], vec[size - 1], t);
		} else
		if (size == 3)
		{
			if (t > 1)
			{
				return cosineInterpolate(vec[1], vec[2], t);
			}
			else
			{
				return cosineInterpolate(vec[0], vec[1], t);
			}
		} else
		if (size == 2)
		{
			return cosineInterpolate(vec[0], vec[1], t);
		} else
		if (size == 1)
		{
			return vec[0];
		}

		return Vector3(0, 0, 0);
	}

	void initializeFromXml(char const * const xmlFile, std::vector<CSceneBase *> &sceneMap, COgreEngine *engine, int const &netConfig);
}

#endif //__UTILS_H_